package demo1;

import javax.naming.Name;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;

public class ReflectClassDemo {
    public static void reflectNewInstance() {
        try {
            Class<?> classStudent = Class.forName("demo1.Student");

            Student student = (Student) classStudent.newInstance();

            System.out.println("获得学生对象："+student);

        }catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }

    // 调用 Student中私有的构造方法
    public static void reflectPrivateConstructor() {
        try {
            Class<?> classStudent = Class.forName("demo1.Student");
            // public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可能会抛异常
            Constructor<?> constructor=classStudent.getDeclaredConstructor(String.class, int.class);
            // 设置为true， 将private 修改成 可修改的
            constructor.setAccessible(true);

            Student student=(Student)constructor.newInstance("gaobo",29);

            System.out.println(student);

        }catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }


    // 反射私有属性
    public static void reflectPrivateField() {
        try {
            Class<?> classStudent = Class.forName("demo1.Student");
            // public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可能会抛异常
            Field field =classStudent.getDeclaredField("name");
            Field field2 =classStudent.getDeclaredField("age");
            // 设置为true， 将private 修改成 可修改的
            field.setAccessible(true);
            field2.setAccessible(true);
            Student student=(Student)classStudent.newInstance();

            field.set(student,"haoshfiod");
            field2.set(student,28);

            System.out.println(student);

        } catch (NoSuchFieldException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }

    }


    // 反射私有方法
    public static void reflectPrivateMethod() {
        try {
            Class<?> classStudent = Class.forName("demo1.Student");
            // public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes) 可能会抛异常
            Method method =classStudent.getDeclaredMethod("eat");
            Method method2 =classStudent.getDeclaredMethod("function", String.class);
            System.out.println("私有方法的方法名为："+method2.getName());

            method.setAccessible(true);
            method2.setAccessible(true);

            Student student=(Student)classStudent.newInstance();

            //method.invoke(student,(Object) "映射的私有eat方法");
            method.invoke(student);
            method2.invoke(student,"我是给私有的function函数传的参数");


        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        } catch (InstantiationException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        }
    }

    public static void main(String[] args) {
        //reflectNewInstance();
       // reflectPrivateConstructor();
        //reflectPrivateField();
        reflectPrivateMethod();
    }
}
